package com.sright.bcard.enterprise.web.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
@Order(1)
public class LogAsoect {

    @Pointcut("execution(* com.sright.bcard.*.*.service.*ServiceImpl.*(..))")
    private void cut() {
    }

    @Around("cut()")
    public Object Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        Object[] args = proceedingJoinPoint.getArgs();
        String targetName = proceedingJoinPoint.getTarget().getClass().getSimpleName();
        String methodName = proceedingJoinPoint.getSignature().getName();
        Class returnType = ((MethodSignature) proceedingJoinPoint.getSignature()).getReturnType();

        long startTime = System.currentTimeMillis();
        try {

            Object rs = proceedingJoinPoint.proceed(args);
            long endTime = System.currentTimeMillis();

            long costTime = endTime - startTime;
            log.info(targetName + ":" +methodName + "call cost time is : {}", costTime + "ms");
            if(null != args && args.length > 0) {
                final Integer[] count = {1};
                for(Object arg : args) {
                    log.info(targetName + ":" +methodName + ": arg" + count[0] + ": {}", arg);
                    count[0]++;
                }
            }
            log.info(targetName + ":" +": returnType : {}", returnType);
            return rs;

        } catch (Exception e) {
            long endTime = System.currentTimeMillis();
            long costTime = endTime - startTime;
            log.error("Service {}.{} params={} RT={} error", targetName, methodName, args, costTime, e);
            throw e;
        }
    }

}
